﻿/*****************************************************************//**
 * @file    FITKAssInstance.h
 * @brief   通用装配实例数据类。

 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-12-04
 *********************************************************************/

#ifndef __FITKASSINSTANCE_H__
#define __FITKASSINSTANCE_H__

#include "FITKAbstractAssInstance.h"

 //#include "eigen3/Eigen/Dense"

namespace Interface
{
    // 前置声明。
    class FITKAbstractTransformTool;

    ///**
    //* @brief  变换信息类
    //* @author Yanzhihui (chanyuantiandao@126.com)
    //* @date   2024-12-10
    //*/
    //class FITKTransformation {
    //public:
    //    /**
    //     * @brief  构造函数.
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    FITKTransformation();
    //    /**
    //     * @brief  用原始数据构建变换.
    //     * @param  matrix 旋转矩阵
    //     * @param  vector 平移向量
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    FITKTransformation(const Eigen::Matrix3d& matrix, const Eigen::Vector3d& vector);
    //    /**
    //     * @brief  构建一个平移变换.
    //     * @param  translation 平移向量
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    FITKTransformation(const Eigen::Vector3d& translation);
    //    /**
    //     * @brief  构建一个旋转变换.
    //     * @param  axisOrigin 旋转轴圆心
    //     * @param  axisDir 旋转轴方向
    //     * @param  angle 旋转角度
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    FITKTransformation(double* axisOrigin, double* axisDir, const double angle);
    //    /**
    //     * @brief  析构函数.
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    ~FITKTransformation() = default;
    //    /**
    //     * @brief  获取原始旋转矩阵（3x3）.
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    Eigen::Matrix3d                          matrix() const;
    //    /**
    //     * @brief  设置原始旋转矩阵（3x3）.
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    void                                     setMatrix(const Eigen::Matrix3d& matrix);
    //    /**
    //     * @brief  获取平移向量.
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    Eigen::Vector3d                          vector() const;
    //    /**
    //     * @brief  获取平移向量.
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    void                                     setVector(const Eigen::Vector3d& vector);
    //    /**
    //     * @brief  获取旋转参数.
    //     * @param  axisOrigin 旋转轴圆心
    //     * @param  axisDir 旋转轴方向
    //     * @param  angle 旋转角度
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    bool                                     isRotation(double* axisOrigin, double* axisDir, double& angle) const;

    //    /**
    //     * @brief  变换叠加（先变换transf2，在执行transf1）
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    friend FITKTransformation operator*(const FITKTransformation& transf1, const FITKTransformation& transf2);
    //    /**
    //     * @brief  点变换
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    friend std::array<double, 3> operator*(const FITKTransformation& transf, const std::array<double, 3> & point);

    //private:
    //    /**
    //     * @brief  3x3旋转矩阵
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    Eigen::Matrix3d _Matrix;
    //    /**
    //     * @brief  平移向量
    //     * @author Yanzhihui (chanyuantiandao@126.com)
    //     * @date   2024-12-10
    //     */
    //    Eigen::Vector3d _Vector;
    //};
    /**
     * @brief   通用装配实例数据类。
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-12-04
     */
    class FITKInerfaceModelAPI FITKAssemblyInstance : public  FITKAbstractAssInstance
    {
        FITKCLASS(Interface, FITKAssemblyInstance);
    public:
        /**
         * @brief   构造函数。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-04
         */
        explicit FITKAssemblyInstance();

        /**
         * @brief   析构函数。[虚函数]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-04
         */
        virtual ~FITKAssemblyInstance();

        /**
         * @brief  构建一个部件实例.
         * @param  modelId 部件ID
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        FITKAssemblyInstance(int modelId);

        /**
         * @brief  构建一个平移的部件实例.
         * @param  modelId 部件ID
         * @param  xyz xyz方向上的平移量数组
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        FITKAssemblyInstance(int modelId, double* xyz);

        /**
         * @brief  构建一个旋转的部件实例.
         * @param  modelId 部件ID
         * @param  pt1 旋转轴第一点坐标
         * @param  pt2 旋转轴第二点坐标
         * @param  angle 旋转角度
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        FITKAssemblyInstance(int modelId, double* pt1, double* pt2, double angle);

        /**
         * @brief  构建一个平移的部件实例.
         * @param  instance 原始实例
         * @param  xyz xyz方向上的平移量数组
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        FITKAssemblyInstance(FITKAssemblyInstance* instance, double* xyz);

        /**
         * @brief  构建一个旋转的部件实例.
         * @param  instance 原始实例
         * @param  pt1 旋转轴第一点方向
         * @param  pt2 旋转轴第二点方向
         * @param  angle 旋转角度
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        FITKAssemblyInstance(FITKAssemblyInstance* instance, double* pt1, double* pt2, double angle);

        /**
         * @brief  平移实例.
         * @param  x x方向上的平移量
         * @param  y y方向上的平移量
         * @param  z z方向上的平移量
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        void transform(double x, double y, double z);

        /**
         * @brief  旋转实例.
         * @param  pt1 旋转轴第一点坐标
         * @param  pt2 旋转轴第二点坐标
         * @param  angle 旋转角度
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
        void rotate(double* pt1, double* pt2, double angle);

        /**
         * @brief   获取平移量。
         * @param   transform：xyz方向平移量
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-04
         */
        void getTransfom(double* transform);

        /**
         * @brief   获取旋转轴。
         * @param   p1：旋转轴第一个点坐标
         * @param   p2：旋转轴第二个点坐标
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-04
         */
        bool getRotateAxis(double* p1, double* p2, double* angle);

        /**
         * @brief   保存变换信息。
         * @param   trans：平移
         * @param   rotatePt1：旋转轴第一点坐标
         * @param   rotatePt2：旋转轴第二点坐标
         * @param   angle：旋转角
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-20
         */
        void setTransform(double* trans, double* rotatePt1, double* rotatePt2, double angle);

        /*@{*/
        // 以下为遗留方法，不建议使用

        /**
        * @brief   工具方法 - 获取变换后的节点坐标。[重写]
        * @param   pointID：节点ID
        * @param   coor：返回坐标
        * @param   modelIndex：模型索引，用于复合模型（一个模型包含多个子模型）
        * @return  是否获取成功
        * @author  ChengHaotian (yeguangbaozi@foxmail.com)
        * @date    2024-12-04
        */
        bool getPointCoor(int pointID, double* coor, int modelIndex = 0) override;

        /**
         * @brief   坐标变换。[重写]
         * @param   iPt：输入坐标
         * @param   oPt：输出坐标
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-23
         */
        void transformPoint(double* iPt, double* oPt) override;

        /**
         * @brief   方向变换。[重写]
         * @param   iDir：输入方向
         * @param   oDir：输出方向
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-23
         */
        void transformDirection(double* iDir, double* oDir) override;

        /**
         * @brief   获取变换矩阵。
         * @param   oMat：矩阵
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-23
         */
        void getMatrix4X4(double oMat[4][4]);

        /**
         * @brief   是否存在变换计算工具。（不存在则使用旋转轴与平移量进行渲染，否则使用变换矩阵。）
         * @return  是否存在
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2025-01-03
         */
        bool hasTransformTool();

    protected:
        /**
         * @brief   初始化变换计算工具。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-20
         */
        void initTransformTool();

    private:
        /**
         * @brief  变换信息
         * @author Yanzhihui (chanyuantiandao@126.com)
         * @date   2024-12-10
         */
         //FITKTransformation _Transformation{};

         /**
          * @brief   变换计算工具。
          * @author  ChengHaotian (yeguangbaozi@foxmail.com)
          * @date    2024-12-20
          */
        Interface::FITKAbstractTransformTool* m_transformTool{ nullptr };

        /**
         * @brief   旋转矩阵。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-23
         */
        double m_matrix[3][3]{ 1.,0.,0.,0.,1.,0.,0.,0.,1. };

        /**
         * @brief   平移向量。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-12-23
         */
        double m_vector[3]{ 0., 0., 0. };

        /**
         * @brief   旋转轴第一点坐标。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2025-01-02
         */
        double m_rotate1[3]{ 0., 0., 0. };

        /**
         * @brief   旋转轴第二点坐标。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2025-01-02
         */
        double m_rotate2[3]{ 0., 0., 0. };

        /**
         * @brief   旋转角。
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2025-01-02
         */
        double m_angle = 0.;
    };
}

#endif // !__FITKASSINSTANCE_H__
